package pl.smath.renderer.model;

import gwt.g2d.client.graphics.Surface;
import gwt.g2d.client.graphics.canvas.Context;
import pl.smath.renderer.renderer.TermRendererException;
import pl.smath.renderer.utils.Cursor;
import pl.smath.renderer.utils.InteractionSocket;
import pl.smath.renderer.utils.Rectangle;

public class ExponentationView extends View {

	private View exponent;
	private View base;
	private Double offset;
	
	public ExponentationView( View base, View exponent) {
		super("^");
		this.setExponent(exponent);
		this.setBase(base);
	}

	/**
	 * render text at the current position
	 * @param canvas
	 */
	@Override
	public void render(Surface canvas, InteractionSocket socket) throws TermRendererException {
		if ((this.getFont() == null)||(this.getFontHeight() == null)) {
			throw new TermRendererException();
		}
		canvas.setFont(this.getFont());
		
		Cursor cursor = new Cursor(this.getCursor().getX(), this.getCursor().getY() - this.getBaselineOffset());
		
		Double minusWidth = this.minusSign.getWidth();
		
		if (this.isNegative()) this.minusSign.render(canvas, cursor);
		
		this.getBase().render(canvas, socket);
		this.getExponent().render(canvas, socket);
		
		if (this.isNegative()) 
			cursor.setX(cursor.getX() + minusWidth + this.getExponent().getWidth());
		else
			cursor.setX(cursor.getX() + this.getExponent().getWidth());

	}
	
	/**
	 * set the position on canvas to render
	 * @param Cursor
	 */
	@Override
	public void setCursor(Cursor cursor) {
		super.setCursor(new Cursor(cursor.getX(), cursor.getY()));
			
		Surface canvas = new Surface();
		canvas.setFont(this.getFont());
		
		Double minusWidth = this.minusSign.getWidth();
			
		Cursor toSet = new Cursor(cursor.getX(), cursor.getY() - this.getBaselineOffset());
		if (this.isNegative()) toSet.setX(toSet.getX() + minusWidth);
		
		this.getBase().setCursor(new Cursor(toSet.getX(), toSet.getY()));
		toSet.setX(toSet.getX() + this.getBase().getWidth());
		this.getExponent().setCursor(new Cursor(toSet.getX(), toSet.getY() - offset));
		
	}
	
	/**
	 * @param font the font to set
	 */
	@Override
	public void setFont(String font) {
		if (font.indexOf("px")!=-1) {
			this.setFontHeight(new Double(font.substring(0, font.indexOf("px"))));
			this.font = font.substring(font.indexOf("px ")+3);
			this.minusSign.setFont(this.font, this.getFontHeight());

			this.setOffset(this.getFontHeight() * 0.5d);
			
			this.getBase().setFont(font);
			
			if (this.getFontHeight() > 8) 
				this.getExponent().setFont((this.getFontHeight() - 4) + "px " + this.font);
			else
				this.getExponent().setFont(font);
			
			update();
		} else {
			this.setFontHeight(null);
			this.font = null;
		}
	}
	
	/**
	 * updates the view after changes
	 */
	@Override
	public void update() {
		Surface surface = new Surface();
		surface.setFont(this.getFont());
		
		Double minusWidth = this.minusSign.getWidth();
		
		this.setRectangle(new Rectangle());
		this.setBaselineOffset(0d);
		
		this.setWidth(this.getBase().getWidth() + this.getExponent().getWidth());
		
		if(this.isNegative())
			this.setWidth(this.getWidth() + minusWidth);
		
		this.setHeight(Math.max(this.getBase().getHeight(), this.getExponent().getHeight() + this.offset));
	}
	
	/**
	 * @param exponent the exponent to set
	 */
	public void setExponent(View exponent) {
		this.exponent = exponent;
	}

	/**
	 * @return the exponent
	 */
	public View getExponent() {
		return exponent;
	}

	/**
	 * @param degree the degree to set
	 */
	public void setBase(View base) {
		this.base = base;
	}

	/**
	 * @return the degree
	 */
	public View getBase() {
		return base;
	}

	/**
	 * @param offset the offset to set
	 */
	public void setOffset(Double offset) {
		this.offset = offset;
	}

	/**
	 * @return the offset
	 */
	public Double getOffset() {
		return offset;
	}


}
